package com.luocj.elephant.demo.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.Point;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.luocj.elephant.demo.Bean.LineChartBean;
import com.luocj.elephant.demo.R;
import com.luocj.elephant.demo.utils.Utils;

import java.util.ArrayList;


public class MyLineChartView extends View {

    private int widthDefault;
    private int heightDefault;
    private int marginDefault;
    private Paint mPaint;
    private Paint lablePaint;
    private Paint textPaint;
    private int textSize;
    private Path mPath;
    private Path mAssistPath;
    private ArrayList<LineChartBean> beans;
    private float lineSmoothness = 0.2f;
    private float drawScale = 1f;
    private PathMeasure mPathMeasure;
    private Paint linePaint;


    public MyLineChartView(Context context) {
        this(context, null);
    }

    public MyLineChartView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyLineChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        widthDefault = Utils.getScreenWidth(context);
        heightDefault = Utils.dip2px(context, 100);
        marginDefault = Utils.dip2px(context, 10);
        textSize = Utils.dip2px(context, 14);
        initPaint();

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyLineChart);
        ta.getDimension(R.styleable.MyLineChart_line_margin, marginDefault);
        ta.getDimension(R.styleable.MyLineChart_text_size, textSize);
        ta.recycle();

    }

    private void initPaint() {
        mPaint = new Paint();
        mPaint.setStrokeWidth(10);
        mPaint.setColor(Color.RED);
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeCap(Paint.Cap.ROUND);

        linePaint = new Paint();
        linePaint.setStrokeWidth(5);
        linePaint.setAntiAlias(true);
        linePaint.setColor(Color.GREEN);


        lablePaint = new Paint();
        lablePaint.setColor(Color.BLACK);
        lablePaint.setAntiAlias(true);
        lablePaint.setStyle(Paint.Style.STROKE);

        /**
         * 文字画笔
         */

        textPaint = new Paint();
        textPaint.setStrokeWidth(1);
        textPaint.setColor(Color.BLACK);
        textPaint.setTextSize(Utils.dip2px(getContext(), 10));
        textPaint.setAntiAlias(true);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width;
        int height;

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else {
            width = widthDefault;
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else {
            height = heightDefault;
        }

        setMeasuredDimension(width, height);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.parseColor("#436EEE"));
        canvas.translate(0, getBottom());

        drawYLable(canvas);
        drawYLine(canvas);

        drawXLine(canvas);
        drawXLable(canvas);

        beans = getLineChartBeans();
        drawDataLines(canvas);

//        measurePath();
//        drawBezier(canvas);
    }

    private void drawBezier(Canvas canvas) {
        Paint paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStrokeWidth(3);
        paint.setStyle(Paint.Style.STROKE);
        //绘制辅助线
        canvas.drawPath(mAssistPath, paint);

        paint.setColor(Color.GREEN);
        Path dst = new Path();
        dst.rLineTo(0, 0);
        float distance = mPathMeasure.getLength() * drawScale;
        if (mPathMeasure.getSegment(0, distance, dst, true)) {
            //绘制线
            canvas.drawPath(dst, paint);
            float[] pos = new float[2];
            mPathMeasure.getPosTan(distance, pos, null);
            //绘制阴影
//            drawShadowArea(canvas, dst, pos);
            //绘制点
//            drawPoint(canvas,pos);
        }
    }

    private void measurePath() {
        mPath = new Path();
        mAssistPath = new Path();
        float prePreviousPointX = Float.NaN;
        float prePreviousPointY = Float.NaN;
        float previousPointX = Float.NaN;
        float previousPointY = Float.NaN;
        float currentPointX = Float.NaN;
        float currentPointY = Float.NaN;
        float nextPointX;
        float nextPointY;

        final int lineSize = 20;

        for (int i = 0; i < lineSize; ++i) {
            if (Float.isNaN(currentPointX)) {
//                Point point = mPointList.get(i);
                LineChartBean lineChartBean = beans.get(i);
                currentPointX = lineChartBean.getxAxis();
                currentPointY = lineChartBean.getyAxis();

            }
            if (Float.isNaN(previousPointX)) {
                //是否是第一个点
                if (i > 0) {
                    LineChartBean lineChartBean = beans.get(i - 1);

//                    Point point = mPointList.get(i - 1);
                    previousPointX = lineChartBean.getxAxis();
                    previousPointY = lineChartBean.getyAxis();
                } else {
                    //是的话就用当前点表示上一个点
                    previousPointX = currentPointX;
                    previousPointY = currentPointY;
                }
            }

            if (Float.isNaN(prePreviousPointX)) {
                //是否是前两个点
                if (i > 1) {
//                    Point point = mPointList.get(i - 2);
                    LineChartBean lineChartBean = beans.get(i - 2);
                    prePreviousPointX = lineChartBean.getxAxis();
                    prePreviousPointY = lineChartBean.getyAxis();
                } else {
                    //是的话就用当前点表示上上个点
                    prePreviousPointX = previousPointX;
                    prePreviousPointY = previousPointY;
                }
            }

            // 判断是不是最后一个点了
            if (i < lineSize - 1) {
//                Point point = mPointList.get(i + 1);
//                nextPointX = point.x;
//                nextPointY = point.y;

                LineChartBean lineChartBean = beans.get(i + 1);
                nextPointX = lineChartBean.getxAxis();
                nextPointY = lineChartBean.getyAxis();

            } else {
                //是的话就用当前点表示下一个点
                nextPointX = currentPointX;
                nextPointY = currentPointY;
            }

            if (i == 0) {
                // 将Path移动到开始点
                mPath.moveTo(currentPointX, currentPointY);
                mAssistPath.moveTo(currentPointX, currentPointY);
            } else {
                // 求出控制点坐标
                final float firstDiffX = (currentPointX - prePreviousPointX);
                final float firstDiffY = (currentPointY - prePreviousPointY);
                final float secondDiffX = (nextPointX - previousPointX);
                final float secondDiffY = (nextPointY - previousPointY);
                final float firstControlPointX = previousPointX + (lineSmoothness * firstDiffX);
                final float firstControlPointY = previousPointY + (lineSmoothness * firstDiffY);
                final float secondControlPointX = currentPointX - (lineSmoothness * secondDiffX);
                final float secondControlPointY = currentPointY - (lineSmoothness * secondDiffY);
                //画出曲线
                mPath.cubicTo(firstControlPointX, firstControlPointY, secondControlPointX, secondControlPointY,
                        currentPointX, currentPointY);
                //将控制点保存到辅助路径上
                mAssistPath.lineTo(firstControlPointX, firstControlPointY);
                mAssistPath.lineTo(secondControlPointX, secondControlPointY);
                mAssistPath.lineTo(currentPointX, currentPointY);
            }

            // 更新值,
            prePreviousPointX = previousPointX;
            prePreviousPointY = previousPointY;
            previousPointX = currentPointX;
            previousPointY = currentPointY;
            currentPointX = nextPointX;
            currentPointY = nextPointY;
        }

        mPathMeasure = new PathMeasure(mPath, false);
    }

    /**
     * 连线
     *
     * @param canvas
     */
    private void drawDataLines(Canvas canvas) {

        int subWidth = (getWidth() - 40) / (beans.size());
        for (int i = 0; i < beans.size(); i++) {
            if (i == beans.size() - 1) return;
            canvas.drawLine(i * subWidth + 20, -beans.get(i).getyAxis() - 50,
                    (i + 1) * subWidth + 20, -beans.get(i + 1).getyAxis() - 50, linePaint);
        }
    }

    @NonNull
    private ArrayList<LineChartBean> getLineChartBeans() {
        //获取数据
        ArrayList<LineChartBean> beans = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            LineChartBean lineChartBean = new LineChartBean();
            lineChartBean.setxAxis(i);
            lineChartBean.setyAxis((float) (Math.random() * 700 + 50));
            beans.add(lineChartBean);
        }
        return beans;
    }

    /**
     * x 轴
     *
     * @param canvas
     */
    private void drawXLable(Canvas canvas) {
        int width = getWidth() - 40;
        float subWidth = width / 20;
        for (int i = 1; i <= 20; i++) {
            canvas.drawText(i + "", (i - 1) * subWidth + 20, -30, textPaint);
        }

    }

    private void drawXLine(Canvas canvas) {
        canvas.drawLine(10, -100, getRight(), -100, mPaint);
    }

    private void drawYLine(Canvas canvas) {
        canvas.drawLine(10, -100, 10, -getBottom(), mPaint);
    }

    private void drawYLable(Canvas canvas) {

    }
}
